package com.spider.spiderflowable.core.service.impl;

import com.spider.spiderflowable.core.entity.vo.FlowableTaskVO;
import com.spider.spiderflowable.core.service.SpiderProcessInstanceService;
import com.spider.spiderflowable.utils.BeanUtils;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * @author xiong.bo
 * @version 1.0
 * @date 2024/5/6 7:58 下午
 */

@Slf4j
@Service
public class SpiderProcessInstanceServiceImpl implements SpiderProcessInstanceService {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;


    @Override
    public List<FlowableTaskVO> startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, Map<String, Object> variables, String tenantId) {

        log.info("启动流程实例_通过流程定义processDefinitionKey:{},businessKey:{},tenantId:{},variables:{}", processDefinitionKey, businessKey, tenantId, variables);
        ProcessInstance processInstance = null;
        if (StringUtils.hasText(businessKey)) {
            processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(
                processDefinitionKey, businessKey, variables, tenantId);
        } else {
            processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(
                processDefinitionKey, variables, tenantId);
        }

        List<Task> list = processInstanceId4Multi(processInstance.getProcessInstanceId());
        List<FlowableTaskVO> taskVO = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            taskVO = BeanUtils.copyList(list, FlowableTaskVO.class);
            for (FlowableTaskVO innerTaskVo : taskVO) {
                innerTaskVo.setProcessDefinitionKey(processInstance.getProcessDefinitionKey());
            }
        } else {
            FlowableTaskVO task = new FlowableTaskVO();
            task.setProcessDefinitionKey(processInstance.getProcessDefinitionKey());
            taskVO.add(task);
        }
        return taskVO;
    }

    @Override
    public void deleteProcessInstance(String processInstanceId, String deleteReason) {
        runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
    }

    @Override
    public void suspendProcessInstanceById(String processInstanceId) {
        runtimeService.suspendProcessInstanceById(processInstanceId);
    }

    @Override
    public void activateProcessInstanceById(String processInstanceId) {
        runtimeService.activateProcessInstanceById(processInstanceId);
    }

    @Override
    public Map<String, Object> getVariables(String executionId) {
        return runtimeService.getVariables(executionId);
    }

    @Override
    public Object getVariable(String executionId, String variableName) {
        return runtimeService.getVariable(executionId, variableName);
    }

    public List<Task> processInstanceId4Multi(String processInstanceId) {
        TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId(processInstanceId).active();
        return new ArrayList<>(taskQuery.list());
    }

}
